#!/usr/bin/perl -w
#$Source: Volumes://MATEOR/prlserverapi/client.pl$
#$Revision: 0.01-0a$
#$Date: June 13, 2012$
#------------
# PrlServerAPI Copyright Matthew Caswell, 2012
#------------
#

use strict;
use Socket;
use Define;
use Storable;
use PrlServer::API qw( $API_release );

 
unless ($#ARGV == 2) {
  die "usage: $0 <host> <server> <port>";
}

my($CLIENT) = PrlServer::API->new (
  proto => 'tcp',
  port => $ARGV [2],
  ip => "$ARGV[1]",
  host => $ARGV [0]
);

$CLIENT->debugOff ();
$CLIENT->debug ($ARGV [1] . "\n");
$CLIENT->debug ($CLIENT->{ipOfServer} . "\n");
$CLIENT->{psaal} = retrieve ('psaal.rc');

# $CLIENT->createClient ();

my($esp);
my($ebp);

$ebp = &Define::String($ebp, '0:1', 'LOGIC'); $CLIENT->debug ($CLIENT->{ipOfServer} . "\n");
$ebp = &Define::String($ebp, '0', 'LOGIC}->{LOW'); $CLIENT->debug ($CLIENT->{ipOfServer} . "\n");
$ebp = &Define::String($ebp, '1', 'LOGIC}->{HIGH'); $CLIENT->debug ($CLIENT->{ipOfServer} . "\n");

$esp = &Define::String($esp, 0, 'SESSION'); $CLIENT->debug ($CLIENT->{ipOfServer} . "\n");
$esp = &Define::String($esp, 'Client', 'SESSION}->{USER'); $CLIENT->debug ($CLIENT->{ipOfServer} . "\n");
$esp = &Define::String($esp, (&Define::pull($ebp, 'LOGIC}->{LOW')), 'SESSION}->{STAT'); $CLIENT->debug ($CLIENT->{ipOfServer} . "\n");
$esp = &Define::String($esp, 0, 'SESSION}->{USAVE'); $CLIENT->debug ($CLIENT->{ipOfServer} . "\n");

print STDERR "PrlServerAPI Client $API_release\n";

sub Init{
  my($this) = @_;
  
  $this->debug ($this->{ipOfServer} . "\n");
  $this->clientPortOut (0x00);
  
  print STDERR $this->clientPortIn ();

  &Define::String ($esp, $this->clientPortIn (), 'SESSION}->{SERVER}->{HOST');
  print STDERR &Define::pull ($esp, 'SESSION}->{SERVER}->{HOST');
  
  print STDERR $this->clientPortIn ();
  
  if (exists $CLIENT->{psaal}->{&Define::pull($esp, 'SESSION}->{SERVER}->{HOST')}->{uname}) {
    &PrepCommand($CLIENT);
    &SendCommand($CLIENT, 'login');
    &PrintFromServer($CLIENT);
    print $CLIENT->{psaal}->{&Define::pull($esp, 'SESSION}->{SERVER}->{HOST')}->{uname} . "\e[0m\n";
    
    my $USER = $CLIENT->{psaal}->{&Define::pull($esp, 'SESSION}->{SERVER}->{HOST')}->{uname};
    &SendRaw($CLIENT, $USER);
    my $login;
    $login->{aaa} = &RecieveFromServer($CLIENT);
    my @aaa = split(/\n/, $login->{aaa});
    if ($aaa[1] == 8) {
      my $pass = $CLIENT->{psaal}->{&Define::pull($esp, 'SESSION}->{SERVER}->{HOST')}->{passw};
      &SendRaw($CLIENT, $pass);
      $login->{aab} = &RecieveFromServer($CLIENT);
      @aaa = split(/\n/, $login->{aab});
      if ($aaa[1] == 1) {
        # Setup the local USER envar.
        chomp $USER;
        $esp = &Define::String($esp, $USER, 'SESSION}->{USER');
        $esp = &Define::String($esp, (&Define::pull($ebp, 'LOGIC}->{HIGH')), 'SESSION}->{STAT');
        print STDERR "You have logged in as user \e[0;31m" . &Define::pull($esp, 'SESSION}->{USER') . "\e[0m.\n";
      }
    }
  }
}

sub PrepCommand { 
  my($this) = @_;
  $this->clientPortOut (0x02);
}

sub SendCommand {
  my($this, $cmd) = @_;
  
  $this->clientPortOut ($cmd . "\$" . &Define::pull ($esp, 'SESSION}->{USER'));
}

sub SendRaw {
  my($this, $data) = @_;
  $this->clientPortOut ($data);
}

sub PrintFromServer {
  my($this) = @_;
  
  print $this->clientPortIn ();
}

sub RecieveFromServer {
  my ($this) = @_;
  
  my $h = $this->clientPortIn ();

  return $h;
}

sub Sendmsg {
  my($this, $msg) = @_;
  
  &PrepCommand ();
  
  $this->clientPortOut ("sendmsg\$" . &Define::pull ($esp, 'SESSION}->{USER'));

  $this->clientPortOut ($msg);
}

sub KillSession {
  my($this) = @_;
  
  $this->clientPortOut (0x01);
  print STDERR "\n";
  exit;
}


my $CATS;
&Init($CLIENT);
my $cmd = 0;
my $msg;
while ($cmd ne "exit") {
  print STDERR "<\$> ";
  $cmd = <STDIN>;
  chomp($cmd);
  my @aab = split(/\:/, $cmd);
  $cmd = $aab[0];
  if ($cmd eq "sendmsg") {
    print ">: ";
    $msg = <STDIN>;
    &Sendmsg($CLIENT, $msg);
    print "Message sent..\n";
  } elsif ($cmd eq "halt") {
    &PrepCommand($CLIENT);
    &SendCommand($CLIENT, $cmd);
    &PrintFromServer($CLIENT); 
    if (&RecieveFromServer($CLIENT) == 0x0F) {
      exit;
    }
  } elsif ($cmd eq "\%clear\%") {
    $cmd = `clear`;
    print $cmd;
  } elsif ($cmd eq "help") {
    &PrepCommand($CLIENT);
    &SendCommand($CLIENT, $cmd);
    &PrintFromServer($CLIENT);
    print "\nClient commands:\n\%clear\%\nexit\n\%START\%\n";
  } elsif ($cmd eq "login") {
    &PrepCommand($CLIENT);
    &SendCommand($CLIENT, $cmd);
    &PrintFromServer($CLIENT);
    my $USER = <STDIN>;
    &SendCommand($CLIENT, $USER);
    my $login;
    $login->{aaa} = &RecieveFromServer($CLIENT);
    my @aaa = split(/\n/, $login->{aaa});
    print $aaa[0];
    if ($aaa[1] == 8) {
      my $pass = <STDIN>;
      &SendCommand($CLIENT, $pass);
      $login->{aab} = &RecieveFromServer($CLIENT);
      @aaa = split(/\n/, $login->{aab});
      print $aaa[0] . "\n";
      if ($aaa[1] == 1) {
        # Setup the local USER envar.
        chomp $USER;
        $esp = &Define::String($esp, $USER, 'SESSION}->{USER');
        $esp = &Define::String($esp, (&Define::pull($ebp, 'LOGIC}->{HIGH')), 'SESSION}->{STAT');
        print "You have logged in as user \e[0;31m" . &Define::pull($esp, 'SESSION}->{USER') . "\e[0m.\n";
        unless (exists $ {$CLIENT->{psaal}->{&Define::pull($esp, 'SESSION}->{SERVER}->{HOST')}} {uname}) {
          print "Would you like to log into this account automatically when you connect to this server?(Y/n): ";
          my $usave = <STDIN>;
          print "[DEBUG]:\n";
          chomp $usave;
          if ($usave eq 'Y' || $usave eq 'y') {
            chomp($pass);
            my($psaal) = {
              uname => &Define::pull($esp, 'SESSION}->{USER'),
              passw => $pass
            };
            $CLIENT->{psaal}->{&Define::pull($esp, 'SESSION}->{SERVER}->{HOST')} = $psaal;
            store $CLIENT->{psaal}, 'psaal.rc';
          }
        }
      } else { print "\n" }
    } else { print "\n" }
  } elsif ($cmd eq '%START%') {
    my @START = split(/\$/, $aab[1]);
    my $proc;
    $proc->{PROC} = $START[0];
    my $shell = "$proc->{PROC}\&";
    my $aac = `$shell`;
  } elsif ($cmd eq "start") {
    &PrepCommand($CLIENT);
    &SendCommand($CLIENT, $cmd);
    &PrintFromServer($CLIENT);
    &SendCommand($CLIENT, $aab[1]);
  } elsif ($cmd eq "\@NEW_ACCOUNT") {
    &PrepCommand($CLIENT);
    &SendCommand($CLIENT, $cmd);
    $CLIENT->{local}->{login}->{aab} = &RecieveFromServer($CLIENT);
    my(@aaa) = split(/\n/, $CLIENT->{local}->{login}->{aab});
    print $aaa[0] . "\n";
    if ($aaa[1] == 1) {
      print "User: ";
      my $USER = <STDIN>;
      print "Password: ";
      my $PW = <STDIN>;
      chomp $USER; chomp $PW;
      my $ACCOUNT = "$USER?$PW";
      &SendCommand($CLIENT, $ACCOUNT);
    }
  } elsif ($cmd eq "\@PASSWD") {
    &PrepCommand($CLIENT);
    &SendCommand($CLIENT, $cmd);
    $CLIENT->{local}->{login}->{aab} = &RecieveFromServer($CLIENT);
    my(@aaa) = split(/\\/, $CLIENT->{local}->{login}->{aab});
    if ($aaa[0] eq "0x08") {
      print $aaa[1];
      my $old_user = <STDIN>;
      chomp $old_user;
      &SendCommand($CLIENT, $old_user);
      $CLIENT->{local}->{login}->{aac} = &RecieveFromServer($CLIENT);
      @aaa = split(/\\/, $CLIENT->{local}->{login}->{aac});
      if ($aaa[0] eq "0x08") {
        print $aaa[1];
        my($new_user) = <STDIN>;
        chomp $new_user;
        &SendCommand($CLIENT, $new_user);
        &PrintFromServer($CLIENT);
      } else {
        &PrintFromServer($CLIENT);
      }
    } else {
      &PrintFromServer($CLIENT);
    }
  } elsif ($cmd eq "logout") {
    &PrepCommand($CLIENT);
    &SendCommand($CLIENT, $cmd);
    &PrintFromServer($CLIENT);
    $esp = &Define::String($ebp, 'LOGIC}->{LOW', 'SESSION}->{STAT');
    $esp = &Define::String($esp, 'Client', 'SESSION}->{USER');
  } else {
    &PrepCommand($CLIENT);
    &SendCommand($CLIENT, $cmd);
    &PrintFromServer($CLIENT);
  }
}
&KillSession($CLIENT);
